package br.com.controller.aula;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;

import org.primefaces.model.UploadedFile;

import br.com.arquitetura.controlador.AbstractMBean;
import br.com.arquitetura.excecoes.BDException;
import br.com.arquitetura.servico.ServiceCadastro;
import br.com.data.hibernate.ArquivoHibernateDAO;
import br.com.data.hibernate.AulaHibernateDAO;
import br.com.model.entidade.Arquivo;
import br.com.model.entidade.Aula;
import br.com.util.setup.StringToMD5;

@ManagedBean
@ViewScoped
public class MBGerenciarArquivo extends AbstractMBean<Arquivo>{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Aula aula;
	private Arquivo arquivo;
	private UploadedFile file;
	private boolean vizualizavel;
	private boolean editavel;
	private Long idAula;
	private String caminho = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/") + "arquivo/";
	
	private AulaHibernateDAO aulaHibernateDAO;
	private ArquivoHibernateDAO arquivoHibernateDAO;
	
	@ManagedProperty(value="#{serviceCadastro}")
	private ServiceCadastro serviceCadastro;
	
	public void setServiceCadastro(ServiceCadastro serviceCadastro) {
		this.serviceCadastro = serviceCadastro;
	}
	
	public void irEditar(){
		editavel = true;
	}
	
	public void mudarVizualizar(){
		vizualizavel = !vizualizavel;
		
	}
	
	public MBGerenciarArquivo() {
		// TODO Auto-generated constructor stub
		
		this.arquivoHibernateDAO = (ArquivoHibernateDAO) getBean("arquivoHibernateDAO");
		this.aulaHibernateDAO = (AulaHibernateDAO) getBean("aulaHibernateDAO");
		
		this.arquivo = new Arquivo();
		
		HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
		idAula = (Long) session.getAttribute("idAulaVizualizacao");
		
		if(idAula == null){
			try {
				FacesContext.getCurrentInstance().getExternalContext().redirect("/educacao/pages/professor/index.jsf");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}else{
			try {
				
				this.aula = this.aulaHibernateDAO.getById(Aula.class,idAula);
			} catch (BDException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	
	public void limpar(){
		this.arquivo = new Arquivo();
		vizualizavel = false;
		editavel = false;
		try {
			this.aula = this.aulaHibernateDAO.getById(Aula.class,idAula);
		} catch (BDException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}
	
	
	
	public boolean isVizualizavel() {
		return vizualizavel;
	}

	public void setVizualizavel(boolean vizualizavel) {
		this.vizualizavel = vizualizavel;
	}

	public boolean isEditavel() {
		return editavel;
	}

	public void setEditavel(boolean editavel) {
		this.editavel = editavel;
	}

	public void editar(){
		try {
			this.serviceCadastro.atualizar(arquivo);
			this.limpar();
			FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("Sucesso", "Arquivo editado com sucesso"));
		} catch (BDException e) {
			// TODO Auto-generated catch block
			FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("Erro", "Erro ao editar o arquivo"));
			e.printStackTrace();
		}
	}
	
	public void excluir(){
		try {
			this.serviceCadastro.excluir(arquivo);
			
			if (arquivo.getArquivo() != null){
				File arquivoRemover = new File(caminho + arquivo.getArquivo());
				arquivoRemover.delete();
			}
			
			this.limpar();
			FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("Sucesso", "Arquivo excluido com sucesso"));
			
		} catch (BDException e) {
			// TODO Auto-generated catch block
			FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("Erro", "Erro ao excluir o arquivo"));
			e.printStackTrace();
		}
	}
	
	public void cadastrar(){
		try {
			if (file != null){
				String nome = file.getFileName();
				String nomeArq = StringToMD5.md5(nome);
				String extensao = "." + nome.substring(nome.lastIndexOf(".")+1);
				
				if (this.arquivoHibernateDAO.getByField(Arquivo.class, "arquivo", nomeArq).size() > 0){
					FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("Erro", "Arquivo com o mesmo nome já existe"));
					return ;
				}
				this.arquivo.setArquivo(nomeArq + extensao);
				
				this.arquivo.setAula(aula);
				this.arquivo.setData(Calendar.getInstance());
				this.serviceCadastro.salvar(arquivo);
				
				try {
					File arquivoLocal = new File(this.caminho + nomeArq + extensao);
					FileOutputStream fos = new FileOutputStream(this.caminho + nomeArq + extensao);
					fos.write(file.getContents());
			    	fos.close();
			    	
			    	this.limpar();
			    	
			    	FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("Sucesso", "Arquivo adicionado com sucesso"));
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("Erro", "Erro ao adicionar arquivo"));
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("Erro", "Erro ao adicionar arquivo"));
					e.printStackTrace();
				}
			}else{
				this.arquivo.setAula(aula);
				this.arquivo.setData(Calendar.getInstance());
				this.serviceCadastro.salvar(arquivo);
				this.limpar();
		    	
		    	FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("Sucesso", "Arquivo adicionado com sucesso"));
			}
			
		} catch (BDException e) {
			// TODO Auto-generated catch block
			FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("Erro", "Erro ao adicionar arquivo"));
			e.printStackTrace();
		}
	}
	
	

	public UploadedFile getFile() {
		return file;
	}

	public void setFile(UploadedFile file) {
		this.file = file;
	}

	public Aula getAula() {
		return aula;
	}

	public void setAula(Aula aula) {
		this.aula = aula;
	}

	public Arquivo getArquivo() {
		return arquivo;
	}

	public void setArquivo(Arquivo arquivo) {
		this.arquivo = arquivo;
	}
	
}
